'''
Gets a problem description and troubleshooting steps for any Chromebook issue.
'''
import PySimpleGUI as sg
from warranty_manager.claim.common import SUBMIT_COLOR, CANCEL_COLOR
from warranty_manager.gui.validation import validate_chromebook_keys


def get_chromebook_non_key_issues():
    '''
    Gets a description and troubleshooting steps for all Chromebook issues
    that are not keyboard-related.
    '''
    return {
        "webcam not working":
        {
            'description': (
                "Webcam doesn't display any images, after being turned on."
            ),
            'troubleshooting': (
                "I checked connections between the webcam cable and motherboard, "
                "and re-seated cable as well, but these didn't fix the issue. "
                "I also rebooted device multiple times, and updated Chrome OS "
                "to the latest version, but these didn't fix the issue either. "
                "Webcam, cable, and motherboard show no signs of physical damage."
            )
        },

        "os missing":
        {
            'description': (
                "'Chrome OS is missing or damaged' message appears on Chromebook screen, "
                "after turning it on."
            ),
            'troubleshooting': (
                "I attempted to reboot device, but "
                "this didn't fix. I also attempted to restore it using HP's RMA "
                "Shim process, but after inserting the USB drive, the Chromebook "
                "just changes to a black screen with the backlight on, and then "
                "nothing happens at all, after multiple attempts. System board "
                "appears to be defective, and shows no signs of damage."
            )
        },

        "backlight only": {
            'description': (
                "The backlight comes on after powering on Chromebook, "
                "but nothing else displays on the screen at all."
            ),
            'troubleshooting': (
                "Tried rebooting device, but this didn't fix. Cannot factory reset (after pressing "
                "Esc + Refresh + Power, device simply reboots to the same blank "
                "screen). Checked that display cable was connected securely "
                "to display panel and motherboard, and checked panel "
                "and motherboard for signs of physical damage; none were found."
            )
        },

        "freezes": {
            'description': (
                "Chrome OS will stop responding, some time after logging "
                "in (e.g., I can't move cursor, click mouse, or type any keys)."
            ),
            'troubleshooting': (
                "Sometimes it takes a few seconds; other times, it takes a few "
                "minutes. Rebooted device, and attempted a complete a factory "
                "reset with HP's RMA Shim process, but it even froze during "
                "the attempt, and now device will not boot at all."
            )
        },

        "no headphones sound": {
            'description': (
                "Can't hear any sound from Chromebook, when using headphones."
            ),
            'troubleshooting': (
                "After plugging the headphones into the device, the sound still "
                "comes through the speakers. I checked sound settings; sound is not"
                "muted, and volume is up. I have also attempted to use multiple "
                "pairs of headphones, and none work (the same headphones work with "
                "other devices). Headphones plug in securely, stay put, and port "
                "shows no signs of physical damage. Also, factory reset unit, "
                "using RMA Shim process, but headphone port test failed, and after "
                "reset was complete, issue still persisted."
            )
        },

        "screen lines": {
            'description': "Chromebook has lines on the screen in ChromeOS.",
            'troubleshooting': (
                "Checked connections between display panel and motherboard, "
                "and all cables were connected securely. Also tried to re-seat "
                "LCD cable, but lines still appeared. LCD panel, cable, "
                "and motherboard show no signs of damage."
            )
        },

        "overheated": {
            'description': "Chromebook has overheated.",
            'troubleshooting': (
                "This is due to a defective DC-in adapter, which is "
                "causing the area around where the AC adapter is plugged in "
                "to start smoking, and begin smoke/melt; as a result, the unit "
                "will no longer charge. I examined the DC-in adapter, and it shows "
                "no signs of physical damage Other Chromebooks do not overheat "
                "when plugged into the same AC adapter/outlet, so those are not "
                "the issue."
            )
        },

        "no backlight": {
            'description': "The Chromebook's backlight appears to have failed.",
            'troubleshooting': (
                "If you look closely at the screen, you can still see everything, but it's "
                "extremely dim. Brightness controls have no effect. Screen is too "
                "dim to successfully complete RMA Shim process. Ensured LCD cable "
                "was securely plugged into display panel and motherboard, "
                "and verified that display panel, LCD cable, and motherboard have "
                "no signs of physical damage."
            )
        },

        "touchpad not clicking": {
            'description': (
                "Chromebook touchpad will not 'click', when pressure is applied "
                "(Chrome OS doesn't register that it was even clicked)."
            ),
            'troubleshooting': (
                "I checked the touchpad cable; it's securely connected to motherboard "
                "and touchpad assembly, and neither shows any signs of damage. "
                "Also rebooted device, and performed a restore with RMA Shim "
                "process, but issue still persisted."
            )
        },

        "no cursor": {
            'description': "Cannot use Chromebook's touchpad to move cursor at all.",
            'troubleshooting': (
                "I rebooted device, re-seated touchpad cable in motherboard "
                "and touchpad assembly, but these didn't fix. I also peformed "
                "a factory reset, using HP's RMA shim process, but it still would "
                "not respond at all (touchpad scroll test failed, during factory "
                "reset). Trackpad, touchpad cable, and motherboard do not have "
                "any signs of physical damage."
            )
        },

        "touchpad falling off": {
            'description': "Chromebook touchpad keeps falling off of device.",
            'troubleshooting': (
                "The adhesive that keeps it stuck to the assembly has failed (which seems "
                "to be a factory defect). I have attempted to re-attach the "
                "touchpad, but it continuously falls off."
            )
        },

        "touchpad sticking": {
            'description': "Chromebook touchpad stays stuck in the down position.",
            'troubleshooting': (
                "I have attempted to adjust the screws on the "
                "assembly, to help it respond normally, but this didn't fix the "
                "issue. The trackpad also shows no signs of physical damage."
            )
        },

        "white screen": {
            'description': "Chromebook turns on, but it only displays a white screen.",
            'troubleshooting': (
                "No other graphics are shown, so it cannot be factory reset. "
                "Ensured that LCD cable was securely plugged into display panel "
                "and motherboard, and re-seated it. Also, checked display panel "
                "for signs of physical damage, and found none."
            )
        },

        "no wireless networks": {
            'description': "No wireless networks are visible in Chrome OS.",
            'troubleshooting': (
                "The device cannot be enrolled or logged into. I Checked that wireless "
                "antennae were securely connected to card, and that card was "
                "properly plugged into motherboard. Also, tried to factory reset, "
                "using RMA shim process; wireless test failed, and problem "
                "persisted after restoration was complete."
            )
        },

        "no wireless connection": {
            'description': (
                "Chromebook can see all available wireless networks, but will not "
                "connect to any of them."
            ),
            'troubleshooting': (
                "ChromeOS icon keeps spinning, and never "
                "actually connects. This happens with any network I try to connect "
                "to, regardless of signal strength. I've also checked that the "
                "wireless card is securely plugged into the motherboard, "
                "and antennae are attached correctly. I also tried to restore "
                "with the RMA shim process, but wireless tests failed."
            )
        },

        "no lights turns on": {
            'description': (
                "Charging or power LEDs doesn't come on at all, when Chromebook "
                "is plugged in to AC power."
            ),
            'troubleshooting': (
                "I Checked the battery connector "
                "on motherboard, and it is securely attached. When other devices "
                "are plugged into the same AC adapter/outlet, their lights comes "
                "on, and they charge, so those are not the issue. Performed RMA "
                "shim process, and battery tests failed, and problem persisted "
                "after restore was complete."
            )
        },

        "no lights will not turn on": {
            'description': (
                "Charging or power LEDs doesn't come on at all, when Chromebook "
                "is plugged in to AC power, and nothing can be seen on the screen."
            ),
            'troubleshooting': (
                "I tried multiple AC adapters/outlets, but it won't respond "
                "with any. Other devices turn on, charge, and hold a charge, "
                "when plugged into those other adapters/outlets, so they are not "
                "the issue. Cannot attempt factory reset."
            )
        },

        "screen flickers": {
            'description': "Chromebook display randomly flickers, when unit is turned on.",
            'troubleshooting': (
                "I rebooted the device, and tried re-seating LCD cable, but it did not "
                "fix the issue. Also attempted to complete RMA shim process, "
                "but screen flicker made it impossible go get all the way through, "
                "as the contents of most of the screen were unintelligible."
            )
        },

        "no charge": {
            'description': (
                "Chromebook's battery icon doesn't show up in Chrome OS, "
                "and battery shuts off whenever AC power is removed."
            ),
            'troubleshooting': (
                "I checked that the battery connector was securely plugged into motherboard, "
                "and re-seated battery cable, but device still will not charge. "
                "Neither battery nor motherboard show any signs "
                "of physical damage. Also, this doesn't happen with other "
                "Chromebooks that use the same adapter and outlet."
            )
        },

        "no video": {
            'description': (
                "Chromebook power and charging lights come on, after power button "
                "is pressed, but nothing displays on the screen at all."
            ),
            'troubleshooting': (
                "I rebooted the device, and ensured LCD cable is securely connected "
                "to back of display panel and motherboard. Also examined device, "
                "and display panel and motherboard show no signs "
                "of physical damage."
            )
        },

        "randomly shuts off": {
            'description': "Chromebook will randomly shut off.",
            'troubleshooting': (
                "I tried rebooting device, and making sure that OS is up-to-date, "
                "but the issue persists. Also checked that AC adapter was securely plugged in, "
                "and battery was securely connected in motherboard. I even tried "
                "to complete RMA shim process, but device shut off during it, "
                "rendering the device unusable."
            )
        },

        "missing dc cover": {
            'description': "Cannot charge Chromebook, using AC adapter.",
            'troubleshooting': (
                "I've tried multiple adapters, but none work. Examined DC-in adapter attached "
                "to motherboard, and external sheath has come off, preventing AC "
                "adapter from being plugged in securely. This seems to be a defect "
                "with the manufacturing (see issue c06063013 in HP WISE)."
            )
        },

        "expanding battery": {
            'description': (
                "Chromebook battery continues to expand when plugged in (and even "
                "when it's not), to the point where it's pushing up on the "
                "keyboard."
            ),
            'troubleshooting': (
                "I've tried multiple, known-good AC adapters/outlets, "
                "but the issue persists. Battery shows no signs "
                "of physical damage, so the cause appears to be related "
                "to battery aging or cell imbalance."
            )
        }
    }


def get_chromebook_key_string(keys):
    '''
    Gets a grammatically-correct string of all keys involved in
    a given Chromebook issue.
    '''
    keys_list = list(keys)

    if len(keys_list) == 1:
        key_string = f"'{keys_list[0]}' key"
    elif len(keys_list) == 2:
        key_string = f'"{keys_list[0]}" and "{keys_list[1]}" keys'
    elif len(keys_list) > 2:
        key_string = ''

        for i, key in enumerate(keys_list):
            if i == len(keys_list) - 1:
                key_string += f'and "{key}" keys'
            else:
                key_string += f'"{key}", '

    return key_string


def get_chromebook_key_issues(keys=None):
    '''
    Gets a description and troubleshooting steps for all Chromebook issues
    that are keyboard-related.
    '''
    if keys and len(keys) == 1:
        key_str = get_chromebook_key_string(keys)
        to_be = 'is'
        to_have = 'has'
        bracket = 'bracket'
        support = 'supports'
        it_they = 'it'
        it_them = 'it'
    elif keys and len(keys) > 1:
        key_str = get_chromebook_key_string(keys)
        to_be = 'are'
        to_have = 'have'
        bracket = 'brackets'
        support = 'supports'
        it_they = 'they'
        it_them = 'them'
    else:
        key_str = to_be = to_have = bracket = support = it_they = it_them = ''

    return {
        "missing keys": {
            'description': f"Chromebook {key_str} {to_have} fallen off.",
            'troubleshooting': (
                "This is due to mechanical failure, from repeated use; "
                "students and teachers are constantly typing on the keyboard, "
                "for up to eight hours a day, five days per week, "
                f"so it seems like the {bracket} that {support} {it_them} {to_be} "
                "unable to take the stress. I have attempted to re-attach the "
                f"{it_them}, but {it_they} won't stay on."
            )
        },

        "stuck keys": {
            'description': f"Chromebook {key_str} {to_be} stuck.",
            'troubleshooting': (
                "This is due to mechanical failure of the brackets, "
                f"preventing {it_them} from releasing. I have attempted to get the "
                f"{it_them} out, but am unable to, and the keyboard shows no signs of damage."
            )
        },

        "inoperable keys": {
            'description': f"Cannot type {key_str} on the keyboard.",
            'troubleshooting': (
                "I checked and re-seated keyboard connector cable, rebooted device several times, "
                "and tried to restore the unit, using HP's RMA Shim tool, "
                f"but {it_they} failed during the testing, and still didn't work, "
                "after process was complete. I also inspected the keyboard "
                "assembly, and didn't find any signs of physical damage."
            )
        }
    }


def get_chromebook_issues_list():
    '''
    Gets an alphabetically-sorted list of all Chromebook issues.
    '''
    all_issues = list( get_chromebook_key_issues() ) + list( get_chromebook_non_key_issues() )
    all_issues.sort()
    return all_issues


def get_chromebook_note_from_issue(issue, keys=None):
    '''
    Gets the correct description and troubleshooting steps from the
    provided Chromebook issue.
    '''
    # Keyboard Issue
    if keys:
        issues = get_chromebook_key_issues(keys)
    # Non-Keyboard Issue
    else:
        issues = get_chromebook_non_key_issues()

    found_issue = issues.get(issue)

    if found_issue:
        return (
            found_issue.get('description'),
            found_issue.get('troubleshooting')
        )
    else:
        return ''


def get_num_chromebook_keys_gui():
    '''Gets the number of Chromebook keys with a given problem.'''
    num = 0 # To always return a number

    layout = [
        [
            sg.Text('Please enter the number of Chromebook keys to add:'),
            sg.Input( key='-NUM-', size=(5, 1) )
        ],
        [
            sg.Submit(button_color=SUBMIT_COLOR),
            sg.Cancel(button_color=CANCEL_COLOR)
        ]
    ]
    window = sg.Window('Number of Chromebook keys', layout)

    while True:
        event, values = window.read()

        if event in (None, 'Cancel'):
            break
        elif event == 'Submit':
            try:
                num = int(values['-NUM-'])
            # a non-number was entered
            except ValueError:
                sg.popup('You must enter a number.', title='Error Message')
            else:
                if 1 <= num <= 5:
                    break
                else:
                    sg.popup(
                        f'You must enter a number between 1 and 5.',
                        title='Error Message'
                    )
                    window['-NUM-'].update('')
        else:
            continue

    window.close()
    return num


def get_chromeboook_keys_gui():
    '''
    Gets the Chromebook keys, part numbers, or notes to add to the
    CSN warranty claim.
    '''
    num = get_num_chromebook_keys_gui()

    if num:
        # To store the data
        keys_set = set()

        layout = []

        for i in range(1, num + 1):
            keys_layout = [sg.Text(f"Chromebook Key #{i}")]
            keys_layout.append(
                sg.Input( key=f'-CHROMEBOOK_KEY_{i}-', size=(10, 1) )
            )

            layout.append(keys_layout)

        layout.append([
            sg.Button('Add Chromebook Key(s)', button_color=SUBMIT_COLOR),
            sg.Cancel(button_color=CANCEL_COLOR)
        ])

        window = sg.Window('Chromebook Keys List', layout)

        while True:
            event, values = window.read()

            if event in (None, 'Cancel'):
                break
            elif event == 'Add Chromebook Key(s)':
                validated_keys = validate_chromebook_keys(values)

                if validated_keys:
                    keys_set.update(validated_keys)
                    sg.popup(
                        f'You have sucessfully added the following Chromebook keys: '
                        f'{validated_keys}.',
                        title='Success Message'
                    )
                    break

                sg.popup_error(
                    f'You have entered one or more invalid Chromebook keys. '
                    'Please try again.',
                    title='Error Message'
                )
            else:
                continue

        window.close()
        return keys_set
    else:
        return set()


def get_chromebook_note_gui():
    '''
    Provides a GUI prompt for the user to select the issue that
    a defective Chromebook is having, in order to get a description
    of the issue, and troubleshooting steps taken to try to fix it.
    '''
    issues_list = get_chromebook_issues_list()

    layout = [
        [sg.Text('Which issue is the Chromebook having?')],
        [sg.Combo( issues_list, key='-ISSUE-', size=(30, 1) )],
        [
            sg.Button('Select Issue', button_color=SUBMIT_COLOR),
            sg.Cancel(button_color=CANCEL_COLOR)
        ]
    ]

    window = sg.Window('Chromebook Issue Selector', layout)

    while True:
        event, values = window.read()

        if event in (None, 'Cancel'):
            window.close()
            return None
        elif event == 'Select Issue':
            if not values['-ISSUE-']:
                sg.popup_error(
                    'You have not selected a Chromebook issue. '
                    'Please choose one, and try again.',
                    title='Error Message'
                )
            elif values['-ISSUE-'] in issues_list:
                chosen_issue = values['-ISSUE-']

                if 'keys' in chosen_issue:
                    chosen_keys = get_chromeboook_keys_gui()

                    if chosen_keys:
                        break

                    sg.popup_error(
                        'If you select a Chromebook key issue, '
                        'you must enter at least one key!',
                        title='Error Message'
                    )
                else:
                    chosen_keys = None
                    break
            else:
                sg.popup_error(
                    'You have selected an invalid Chromebook issue. '
                    'Please try again.',
                    title='Error Message'
                )
                continue
        else:
            continue

    window.close()
    return get_chromebook_note_from_issue(chosen_issue, keys=chosen_keys)
